using System;
using Headsight.BPMN2WF.BPMN.Schemas;

namespace Headsight.BPMN2WF.Testing.TestObjCtors
{
    /// <summary>
    /// <see cref="tInclusiveGateway"/> <see cref="ITestObjCtor{T}"/>.
    /// </summary>
    public class tGatewayInclusiveCtor : ITestObjCtor<tInclusiveGateway>
    {
        private readonly ItProcessCtor _parent;
        private readonly String _id;
        private tSequenceFlow _seqFlow;
        private String _name;
        private tSequenceFlow _seqFlowDefault;

        public tGatewayInclusiveCtor(ItProcessCtor tProcessCtor, string id)
        {
            _parent = tProcessCtor;
            _id = id;
        }

        public tGatewayInclusiveCtor WithName(String name)
        {
            _name = name;

            return this;
        }

        public tGatewayInclusiveCtor IfExpression(String expression)
        {
            var seqFlow = new tSequenceFlow
            {
                id = Guid.NewGuid().ToString(),
                sourceRef = _id,
                conditionExpression = new tFormalExpression { Text = new[] { expression } }
            };

            _parent.With(seqFlow);
            _seqFlow = seqFlow;

            return this;
        }

        public tGatewayInclusiveCtor ThenTask(Type type, String id2, String name2)
        {
            var task = (tTask)Activator.CreateInstance(type);
            task.id = id2;
            task.name = name2;

            _seqFlow.targetRef = task.id;
            _parent.With(task);
            return this;
        }

        public tInclusiveGateway Create()
        {
            var result = new tInclusiveGateway { id = _id, name = _name };

            if (_seqFlowDefault != null)
            {
                result.@default = _seqFlowDefault.id;
            }

            return result;
        }

        public tGatewayInclusiveCtor Default()
        {
            var seqFlow = new tSequenceFlow
            {
                id = Guid.NewGuid().ToString(),
                sourceRef = _id,
            };

            _parent.With(seqFlow);
            _seqFlow = _seqFlowDefault = seqFlow;

            return this;
        }
    }
}